﻿using System;
using System.Collections;
using System.Collections.Generic;
using RAP.Framework.Libary.Utils;
using System.Collections.Concurrent;
using RAP.Framework.Libary.DomTemplateBuilder.ContentRender;
using System.Text.RegularExpressions;
using RAP.Framework.Libary.DomTemplateBuilder.Interface;

namespace RAP.Framework.Libary.DomTemplateBuilder
{
  public static class ExpressionUtils
  {
    /// <summary>
    /// 获取对象的值
    /// </summary>
    /// <param name="fieldName"></param>
    /// <param name="rootParamObject"></param>
    /// <param name="parentParamObject"></param>
    /// <param name="context"></param>
    /// <param name="getDefaultValue"></param>
    /// <returns></returns>
    public static object GetFieldValue(string fieldName, object rootParamObject, object parentParamObject, ITemplateRenderContext context, Func<object> getDefaultValue = null)
    {
      if (!string.IsNullOrEmpty(fieldName))
      {
        if (fieldName.StartsWith(Consts.ROOT_PREFIX))
        {
          return rootParamObject.GetValue(fieldName.Substring(Consts.ROOT_PREFIX.Length + 1));
        }
        if (fieldName.StartsWith(Consts.PARAM_PREFIX))
        {
          return rootParamObject.GetValue(fieldName.Substring(Consts.PARAM_PREFIX.Length + 1));
        }
        if (fieldName.StartsWith(Consts.CONTEXT_PREFIX))
        {
          return context.GetValue(fieldName.Substring(Consts.CONTEXT_PREFIX.Length + 1));
        }
        if (fieldName.StartsWith(Consts.PARENT_PREFIX))
        {
          return parentParamObject.GetValue(fieldName.Substring(Consts.PARENT_PREFIX.Length + 1));
        }
        if (fieldName.StartsWith(Consts.CURRENT_ATTRIBUTES))
        {
          return context.CurrentAttributes != null ? context.CurrentAttributes[fieldName.Substring(Consts.CURRENT_ATTRIBUTES.Length + 1)] : null;
        }
      }
      if (getDefaultValue != null)
      {
        return getDefaultValue();
      }
      return null;
    }

    /// <summary>
    /// 设置对象的值
    /// </summary>
    /// <param name="fieldName"></param>
    /// <param name="value"></param>
    /// <param name="rootParamObject"></param>
    /// <param name="parentParamObject"></param>
    /// <param name="context"></param>
    /// <param name="defaultSet"></param>
    public static void SetFieldValue(string fieldName, object value, object rootParamObject, object parentParamObject, ITemplateRenderContext context, Action defaultSet = null)
    {
      if (!string.IsNullOrEmpty(fieldName))
      {
        if (fieldName.StartsWith(Consts.ROOT_PREFIX))
        {
          rootParamObject.SetValue(fieldName.Substring(Consts.ROOT_PREFIX.Length), value);
          return;
        }
        if (fieldName.StartsWith(Consts.PARAM_PREFIX))
        {
          rootParamObject.SetValue(fieldName.Substring(Consts.PARAM_PREFIX.Length), value);
          return;
        }

        if (fieldName.StartsWith(Consts.CONTEXT_PREFIX))
        {
          context.SetValue(fieldName.Substring(Consts.CONTEXT_PREFIX.Length), value);
          return;
        }

        if (fieldName.StartsWith(Consts.PARENT_PREFIX))
        {
          parentParamObject.SetValue(fieldName.Substring(Consts.PARENT_PREFIX.Length), value);
          return;
        }
      }
      if (defaultSet != null)
      {
        defaultSet();
        return;
      }
      if (fieldName.IsNotNullOrEmpty())
      {
        parentParamObject.SetValue(fieldName, value);
      }
    }

    /// <summary>
    /// 字段名称表达式渲染器缓存
    /// </summary>
    public static IDictionary<string, Func<object, object, ITemplateRenderContext, string>> FieldNameRenders = new ConcurrentDictionary<string, Func<object, object, ITemplateRenderContext, string>>();

    /// <summary>
    /// 获取字段名称表达式的值
    /// </summary>
    /// <param name="fieldName"></param>
    /// <param name="rootParamObject"></param>
    /// <param name="parentParamObject"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public static string GetFieldName(string fieldName, object rootParamObject, object parentParamObject, ITemplateRenderContext context)
    {
      fieldName = fieldName.Trim();
      if (fieldName.IsNullOrEmpty())
      {
        return string.Empty;
      }
      if (fieldName == Consts.VALUE_PREFIX)
      {
        return fieldName;
      }
      Func<object, object, ITemplateRenderContext, string> fun = null;
      if (FieldNameRenders.TryGetValue(fieldName, out fun))
      {
        return fun(rootParamObject, parentParamObject, context);
      }
      if (fieldName.StartsWith(Consts.EXPRESSION_FLAG))
      {
        IContentRender render = DomTemplateManager.GetContentRender(Consts.REPLACE_RENDER_ID);
        fun = FieldNameRenders[fieldName] = render.CompileRender(fieldName.Replace(Consts.EXPRESSION_FLAG, ""));
        return fun(rootParamObject, parentParamObject, context);
      }
      return ExpressionUtils.GetFieldValue(fieldName, rootParamObject, parentParamObject, context, () => { return fieldName; }) as string;
    }


    private static Regex _expTestRegx = new Regex(" and | or ");

    /// <summary>
    /// 处理C#表达式
    /// </summary>
    /// <param name="expression"></param>
    /// <returns></returns>
    public static string ParseCSharpExpression(string expression)
    {
      if (expression.IsNotNullOrEmpty())
      {
        if (_expTestRegx.IsMatch(expression))
        {
          expression = expression.Replace(" and ", " && ").Replace(" or ", " || ");
        }
      }
      return expression;
    }

  }
}
